home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / dbwrend / source / fil.c < prev    next >
Text File  |  1989-10-31  |  19KB  |  549 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *                  Copyright (c) 1987, David B. Wecker                 *
  4.  *                          All Rights Reserved                         *
  5.  *                                                                      *
  6.  * This file is part of DBW_Render                                      *
  7.  *                                                                      *
  8.  * DBW_Render is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts               *
  10.  * responsibility to anyone for the consequences of using it or for     *
  11.  * whether it serves any particular purpose or works at all, unless     *
  12.  * he says so in writing. Refer to the DBW_Render General Public        *
  13.  * License for full details.                                            *
  14.  *                                                                      *
  15.  * Everyone is granted permission to copy, modify and redistribute      *
  16.  * DBW_Render, but only under the conditions described in the           *
  17.  * DBW_Render General Public License. A copy of this license is         *
  18.  * supposed to have been given to you along with DBW_Render so you      *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named COPYING. Among other things, the copyright notice and this     *
  21.  * notice must be preserved on all copies.                              *
  22.  ************************************************************************
  23.  *                                                                      *
  24.  * Authors:                                                             *
  25.  *      DBW - David B. Wecker                                           *
  26.  *      jhl - John H. Lowery                                            *
  27.  *                                                                      *
  28.  * Versions:                                                            *
  29.  *      V1.0  870125 DBW - First released version                       *
  30.  *      V1.01 880916 jhl - IBM PC (VGA/MCGA) conversion                 *
  31.  *            890121 jhl - MAXROW & MAXCOL become variables, add        *
  32.  *                         'D' command for Display max <hor> <vert>     *
  33.  *      V1.02 891031 jhl - add MAXCOL and MAXROW as first two integers  *
  34.  *                         in output file, so multiple formats can be   *
  35.  *                         supported.                                   * 
  36.  *                                                                      *
  37.  ************************************************************************/
  38.  
  39. #define MODULE_FILEIO
  40. #include "ray.h"
  41.  
  42. static long         *fracopp;
  43. static triangle     *scr_t;
  44. static extent       *scr_e;
  45. static sphere       *scr_s;
  46. static quad         *scr_q;
  47. static ring         *scr_r;
  48. static cylinder     *scr_c;
  49. static int          whichf;
  50.  
  51. void dumpnode(n)
  52. node    *n;
  53. {
  54.      while (n) 
  55.      {
  56.           switch (n->kind) 
  57.           {
  58.           case EXTENT :
  59.                printf("extent\n");
  60.                vecdump(eptr(n)->center,"center");
  61.                printf("radius = %f\n",eptr(n)->radius);
  62.                dumpnode(((extent *) n)->sub);
  63.                break;
  64.  
  65.           case SPHERE :
  66.                printf("sphere\n");
  67.                break;
  68.  
  69.           case TRIANGLE :
  70.  
  71.                printf("triangle\n");
  72.                break;
  73.  
  74.           case QUAD :
  75.                printf("quad\n");
  76.                break;
  77.  
  78.           case RING :
  79.                printf("ring\n");
  80.                break;
  81.  
  82.           default :
  83.  
  84.                printf("UNKNOWN KIND %d\n",n->kind);
  85.                break;
  86.           }
  87.           n = n->next;
  88.      }
  89.      printf("end\n");
  90. }
  91.  
  92. void copyattr( oa, na )
  93. attributes *oa, *na;
  94. {
  95.      na->ref = oa->ref;
  96.      na->idx = oa->idx;
  97.      na->fuz = oa->fuz;
  98.      na->tex = oa->tex;
  99.      veccopy( oa->tra, na->tra );
  100.      veccopy( oa->amb, na->amb );
  101.      veccopy( oa->dif, na->dif );
  102. }
  103.  
  104. void read_vec(v)
  105. vector  v;
  106. {
  107.      fscanf(df,"%f %f %f",&v[0],&v[1],&v[2]);
  108. }
  109.  
  110. void read_attr(attr)
  111. attributes *attr;
  112. {
  113.      fscanf(df,"%d %f %f %f",&attr->tex,&attr->fuz,&attr->ref,&attr->idx);
  114.      read_vec(attr->tra);
  115.      read_vec(attr->amb);
  116.      read_vec(attr->dif);
  117.      if (attr->tra[0] > 0.0 || attr->tra[1] > 0.0 || attr->tra[2] > 0.0)
  118.           allopaque = 0;
  119.      attr->fuz /= 10.0;  /* Assume more reasonable scale */
  120. }
  121.  
  122. void dofractal(level,a,b,c,attr)
  123. int         level;
  124. vector      a,b,c;
  125. attributes  *attr;
  126. {
  127.      float       aclen,bclen,ablen;
  128.      vector      ab,ac,bc,abbump,acbump,bcbump,v1;
  129.      long        *savedopp;
  130.  
  131.      if (level == 1) 
  132.      {
  133.           CHECK_ALLOC(scr_t,triangle);
  134.           *fracopp = (long)scr_t;
  135.           tptr(*fracopp)->next = NULL;
  136.           tptr(*fracopp)->kind = TRIANGLE;
  137.           copyattr(attr,&tptr(*fracopp)->attr);
  138.           veccopy(a,tptr(*fracopp)->position);
  139.           vecsub(c,a,ac);
  140.           veccopy(ac,tptr(*fracopp)->ve);
  141.           vecsub(b,a,ab);
  142.           veccopy(ab,tptr(*fracopp)->vp);
  143.           fracopp = (long *) &tptr(*fracopp)->next;
  144.      }
  145.      else
  146.      {
  147.           level--;
  148.           /* compute four subfaces */
  149.  
  150.           /* length of edges */
  151.           vecsub(a,c,v1);
  152.           aclen = norm(v1);
  153.           vecsub(a,b,v1);
  154.           ablen = norm(v1);
  155.           vecsub(b,c,v1);
  156.           bclen = norm(v1);
  157.  
  158.           /* edge midpoints */
  159.           vecsum(a,c,ac);
  160.           vecscale(0.5,ac,ac);
  161.           vecsum(a,b,ab);
  162.           vecscale(0.5,ab,ab);
  163.           vecsum(b,c,bc);
  164.           vecscale(0.5,bc,bc);
  165.  
  166.           /* midpoint perturbations */
  167.           noise3(ac,acbump);
  168.           if (ac[1] == 0.0)
  169.                acbump[1] = 0.0;
  170.           noise3(ab,abbump);
  171.           if (ab[1] == 0.0)
  172.                abbump[1] = 0.0;
  173.           noise3(bc,bcbump);
  174.           if (bc[1] == 0.0)
  175.                bcbump[1] = 0.0;
  176.           acbump[0] *= fractal[whichf].xscale;
  177.           acbump[1] *= fractal[whichf].yscale;
  178.           acbump[2] *= fractal[whichf].zscale;
  179.  
  180.           bcbump[0] *= fractal[whichf].xscale;
  181.           bcbump[1] *= fractal[whichf].yscale;
  182.           bcbump[2] *= fractal[whichf].zscale;
  183.  
  184.           abbump[0] *= fractal[whichf].xscale;
  185.           abbump[1] *= fractal[whichf].yscale;
  186.           abbump[2] *= fractal[whichf].zscale;
  187.  
  188.           /* scale the perturbations proportional to side length */
  189.           vecscale(aclen,acbump,acbump);
  190.           vecscale(ablen,abbump,abbump);
  191.           vecscale(bclen,bcbump,bcbump);
  192.  
  193.           /* new perturbed midpoints */
  194.           vecsum(abbump,ab,ab);
  195.           vecsum(acbump,ac,ac);
  196.           vecsum(bcbump,bc,bc);
  197.  
  198.           CHECK_ALLOC(scr_e,extent);
  199.           *fracopp = (long)scr_e;
  200.           eptr(*fracopp)->next = NULL;
  201.           eptr(*fracopp)->kind = EXTENT;
  202.           eptr(*fracopp)->sub = NULL;
  203.           savedopp = &*fracopp;
  204.           fracopp = (long *) &eptr(*fracopp)->sub;
  205.  
  206.           dofractal(level,a, ab,ac,attr);
  207.           dofractal(level,ac,bc,c, attr);
  208.           dofractal(level,ab,b, bc,attr);
  209.           dofractal(level,ac,ab,bc,attr);
  210.  
  211.           fracopp = (long *) &eptr(*savedopp)->next;
  212.      }
  213. }
  214.  
  215. void readimagefile(opp)
  216. long *opp;
  217. {
  218.      triangle    temp;
  219.      vector      a,b,c;
  220.  
  221.      while (EOF != fscanf(df,"%1s",str))
  222.           switch(str[0]) 
  223.           {
  224.           case 'D' :
  225.                fscanf(df,"%d %d",&MAXCOL,&MAXROW); 
  226.                if (MAXCOL > MAXX)
  227.                     MAXCOL = MAXX;
  228.                if (MAXROW > MAXY)
  229.                     MAXROW = MAXY;
  230.                break;
  231.           case 'R' :
  232.                fscanf(df,"%f",&maxhours);
  233.                break;
  234.           case 'N' :
  235.                fscanf(df,"%f",&idxref);
  236.                break;
  237.           case 'Z' :
  238.                fscanf(df,"%d",&histogram);
  239.                break;
  240.           case 'a' :
  241.                fscanf(df,"%f",&ambscale);
  242.                break;
  243.           case 'A' :
  244.                fscanf(df,"%d %f",&antialias,&variance);
  245.                break;
  246.           case 'F' :
  247.                fscanf(df,"%f %f",&aperture,&focus);
  248.                break;
  249.           case 'M' :
  250.                fscanf(df,"%d %d %d",&ambientlight,&amblitnum,&amblitdenom);
  251.                break;
  252.           case '&' :
  253.                fscanf(df,"%d %d",&startrow,&endrow); 
  254.                break;
  255.           case '*' :
  256.                fgets(fname,255,df);     /* get, and display    */ 
  257.                printf("%s",fname);
  258.                break;
  259.           case '!' :
  260.                fgets(fname,255,df);     /* get, and throw away */
  261.                break;
  262.           case 'b' :
  263.                read_vec(backgroundval);
  264.                break;
  265.           case 'w' :
  266.                read_vec(wave[numwaves].center);
  267.                fscanf(df,"%f",&wave[numwaves].wavelength);
  268.                fscanf(df,"%f",&wave[numwaves].amplitude);
  269.                fscanf(df,"%f",&wave[numwaves].drag);
  270.                fscanf(df,"%f",&wave[numwaves].propagate);
  271.                wave[numwaves].wavelength /= 2.0;  /* need half-wave */
  272.                wave[numwaves].propagate  /= 2.0;  /* need half-wave */
  273.                numwaves++;
  274.                break;
  275.           case 'g' :
  276.                read_vec(blend[numblends].color);
  277.                fscanf(df,"%f",&blend[numblends].start);
  278.                fscanf(df,"%f",&blend[numblends].scale);
  279.                numblends++;
  280.                break;
  281.           case 'n' :
  282.                fscanf(df,"%f",&snow[numsnows].start);
  283.                fscanf(df,"%f",&snow[numsnows].altscale);
  284.                fscanf(df,"%f",&snow[numsnows].altfactor);
  285.                fscanf(df,"%f",&snow[numsnows].threshhold);
  286.                numsnows++;
  287.                break;
  288.           case 'p' :
  289.                fscanf(df,"%f",&pebble[numpebbles].scale);
  290.                fscanf(df,"%f",&pebble[numpebbles].zoom);
  291.                numpebbles++;
  292.                break;
  293.           case 'k' :
  294.                read_vec(checker[numcheckers].color);
  295.                fscanf(df,"%f",&checker[numcheckers].x);
  296.                fscanf(df,"%f",&checker[numcheckers].y);
  297.                fscanf(df,"%f",&checker[numcheckers].z);
  298.                fscanf(df,"%f",&checker[numcheckers].bevel);
  299.                fscanf(df,"%f",&checker[numcheckers].angle);
  300.                fscanf(df,"%d", &checker[numcheckers].beveltype);
  301.                checker[numcheckers].bevel /= checker[numcheckers].x;
  302.                numcheckers++;
  303.                break;
  304.           case 'H' :
  305.                read_vec(haze[numhazes].color);
  306.                fscanf(df,"%f",&haze[numhazes].distscale);
  307.                numhazes++;
  308.                break;
  309.           case 'f' :
  310.                fscanf(df,"%d", &fractal[numfractals].level);
  311.                fscanf(df,"%f",&fractal[numfractals].xscale);
  312.                fscanf(df,"%f",&fractal[numfractals].yscale);
  313.                fscanf(df,"%f",&fractal[numfractals].zscale);
  314.                fscanf(df,"%d", &fractal[numfractals].texture);
  315.                numfractals++;
  316.                break;
  317.           case 'm' :
  318.                read_vec(marble[nummarble].veincolor);
  319.                fscanf(df,"%f",&marble[nummarble].xscale);
  320.                fscanf(df,"%f",&marble[nummarble].turbscale);
  321.                fscanf(df,"%d", &marble[nummarble].squeeze);
  322.                nummarble++;
  323.                break;
  324.           case 'd' :
  325.                read_vec(wood[numwoods].othercolor);
  326.                fscanf(df,"%f",&wood[numwoods].thickscale);
  327.                fscanf(df,"%f",&wood[numwoods].ringspacing);
  328.                fscanf(df,"%f",&wood[numwoods].turbscale);
  329.                fscanf(df,"%d", &wood[numwoods].squeeze);
  330.                numwoods++;
  331.                break;
  332.           case 'e' :
  333.                read_vec(eye);
  334.                read_vec(vrp);
  335.                read_vec(vu);
  336.                vecscale((float) MAXCOL / 256.0,vrp,vrp);  /* uniform scale */
  337.                cross(vrp,vu,vr);
  338.                cross(vr,vrp,vu);
  339.                normalize(vu);
  340.                normalize(vr);
  341.                vecsum(vrp,eye,vrp);
  342.                break;
  343.           case 'l' :
  344.                light[numlits].kind = 0;
  345.                read_vec(light[numlits].intensity);
  346.                read_vec(light[numlits].direction);
  347.                normalize(light[numlits++].direction);
  348.                break;
  349.           case 'L' :
  350.                light[numlits].kind = 1;
  351.                read_vec(light[numlits].intensity);
  352.                read_vec(light[numlits].direction);
  353.                fscanf(df,"%f",&light[numlits].distscale);
  354.                fscanf(df,"%f",&light[numlits].radius);
  355.                light[numlits].distscale = 
  356.                  light[numlits].distscale * light[numlits].distscale;
  357.                numlits++;
  358.                break;
  359.           case '{' :
  360.                CHECK_ALLOC(scr_e,extent);
  361.                *opp = (long)scr_e;
  362.                eptr(*opp)->next = NULL;
  363.                eptr(*opp)->kind = EXTENT;
  364.                eptr(*opp)->sub = NULL;
  365.                readimagefile(&eptr(*opp)->sub);
  366.                opp = (long *) &eptr(*opp)->next;
  367.                break;
  368.           case '}' :
  369.                return;
  370.                break;
  371.           case 's' :
  372.                CHECK_ALLOC(scr_s,sphere);
  373.                *opp = (long)scr_s;
  374.                sptr(*opp)->next = NULL;
  375.                sptr(*opp)->kind = SPHERE;
  376.                read_attr(&sptr(*opp)->attr);
  377.                read_vec(sptr(*opp)->center);
  378.                fscanf(df,"%f",&sptr(*opp)->radius);
  379.                opp = (long *) &sptr(*opp)->next;
  380.                break;
  381.           case 't' :
  382.                CHECK_ALLOC(scr_t,triangle);
  383.                *opp = (long)scr_t;
  384.                tptr(*opp)->next = NULL;
  385.                tptr(*opp)->kind = TRIANGLE;
  386.                read_attr(&tptr(*opp)->attr);
  387.                read_vec(tptr(*opp)->position);
  388.                read_vec(tptr(*opp)->ve);
  389.                read_vec(tptr(*opp)->vp);
  390.                opp = (long *) &tptr(*opp)->next;
  391.                break;
  392.           case 'x' :
  393.                read_attr(&temp.attr);
  394.                read_vec(temp.position);
  395.                read_vec(c);
  396.                read_vec(b);
  397.                whichf = temp.attr.tex - 60;
  398.                temp.attr.tex = fractal[whichf].texture;
  399.                fracopp = &*opp;
  400.                dofractal(fractal[whichf].level,
  401.                  temp.position,b,c,&temp.attr);
  402.                opp = &*fracopp;
  403.                break;
  404.           case 'q' :
  405.                CHECK_ALLOC(scr_q,quad);
  406.                *opp = (long)scr_q;
  407.                qptr(*opp)->next = NULL;
  408.                qptr(*opp)->kind = QUAD;
  409.                read_attr(&qptr(*opp)->attr);
  410.                read_vec(qptr(*opp)->position);
  411.                read_vec(qptr(*opp)->ve);
  412.                read_vec(qptr(*opp)->vp);
  413.                opp = (long *) &qptr(*opp)->next;
  414.                break;
  415.           case 'r' :
  416.                CHECK_ALLOC(scr_r ,ring);
  417.                *opp = (long)scr_r;
  418.                rptr(*opp)->next = NULL;
  419.                rptr(*opp)->kind = RING;
  420.                read_attr(&rptr(*opp)->attr);
  421.                read_vec(rptr(*opp)->position);
  422.                read_vec(rptr(*opp)->ve);
  423.                read_vec(rptr(*opp)->vp);
  424.                fscanf(df,"%f",&rptr(*opp)->minrad);
  425.                fscanf(df,"%f",&rptr(*opp)->maxrad);
  426.                rptr(*opp)->minrad =
  427.                  rptr(*opp)->minrad * rptr(*opp)->minrad;
  428.                rptr(*opp)->maxrad =
  429.                  rptr(*opp)->maxrad *rptr(*opp)->maxrad;
  430.                opp = (long *) &rptr(*opp)->next;
  431.                break;
  432.           case 'c' :
  433.                CHECK_ALLOC(scr_c ,cylinder);
  434.                *opp = (long)scr_c;
  435.                cptr(*opp)->next = NULL;
  436.                cptr(*opp)->kind = CYLINDER;
  437.                read_attr(&cptr(*opp)->attr);
  438.                read_vec(cptr(*opp)->bottom);
  439.                read_vec(cptr(*opp)->top);
  440.                fscanf(df,"%f",&cptr(*opp)->a);
  441.                fscanf(df,"%f",&cptr(*opp)->b);
  442.                fscanf(df,"%f",&cptr(*opp)->c);
  443.                opp = (long *) &cptr(*opp)->next;
  444.                break;
  445.           default  :
  446.                sprintf(fname,"Bad command char '%c' encountered",str[0]);
  447.                ERROR(fname);
  448.                break;
  449.           }
  450. }
  451.  
  452. void getinput(argc,argv)
  453. int     argc;
  454. char    **argv;
  455. {
  456.      int       i;
  457.      char      *s, *strchr();
  458.      rextent   re;
  459.  
  460.      if (argc == 1) 
  461.      {
  462.           printf("Scene description file? ");
  463.           scanf("%s",fname);
  464.      }
  465.      else
  466.           sprintf(fname,"%s",argv[1]);
  467.  
  468.      /* if no filetype specified, default it */
  469.  
  470.      if (strchr( fname, '.' ) == NULL)
  471.      {
  472.           strcat( fname, ".DAT" );
  473.      }
  474.  
  475.      df = fopen(fname,"r");
  476.      if (df == NULL)                               /* v1.01  */
  477.           ERROR("Error opening input file.");       /* v1.01  */
  478.  
  479.      /* get name portion of file, append .$ST to it for statistics */
  480.  
  481.      strcpy( outname, fname );
  482.      s = strchr( outname, '.');              /* guaranteed to be there */
  483.      if (s == NULL)
  484.           s = outname + strlen(outname);     /* but just to be sure... */
  485.  
  486.      *s = '\0';
  487.      strcat( outname, ".$ST" );
  488.      fpout = fopen(outname,"w");
  489.      if (fpout == NULL)                             /* v1.01  */
  490.           ERROR("Error opening statistics file.");  /* v1.01  */
  491.  
  492.  
  493.      readimagefile(&root);
  494.  
  495.      getextent(root,&re);
  496.  
  497.      /* dumpnode(root);   DEBUG output */
  498.  
  499.      fclose(df);
  500. }
  501.  
  502. void write_scanline()
  503. {
  504.      int siz;
  505.  
  506.      fwrite(&sline,1,sizeof(int),fp);
  507.  
  508. /*- 1/21/89 ---
  509.     fwrite(redline,1,sizeof(scanlinetype),fp);
  510.     fwrite(greenline,1,sizeof(scanlinetype),fp);
  511.     fwrite(blueline,1,sizeof(scanlinetype),fp);
  512. -*/
  513.      siz = (MAXCOL/PPW)*sizeof(int);     /* file line size */
  514.      fwrite(redline,1,siz,fp);
  515.      fwrite(greenline,1,siz,fp);
  516.      fwrite(blueline,1,siz,fp);
  517.  
  518.      sline++;
  519. }
  520.  
  521. void getoutput(argc,argv)
  522. int     argc;
  523. char    **argv;
  524. {
  525.      if (argc == 1) 
  526.      {
  527.           printf( "File name to save picture (.tmp)? " );
  528.           scanf( "%s", fname );
  529.      }
  530.      else
  531.           sprintf(fname,"%s.tmp",argv[1]);
  532.  
  533. #ifdef IBM_PC
  534.      fp = fopen(fname,"wb");   /* V1.01 - IBM level 2 i/o must be binary */
  535. #else
  536.      fp = fopen(fname,"w");
  537. #endif
  538.  
  539.      if (fp == NULL)
  540.      {
  541.           ERROR( "Error creating output file." );
  542.      }
  543.      else
  544.      {
  545.           fwrite(&MAXCOL,1,sizeof( MAXCOL ),fp);
  546.           fwrite(&MAXROW,1,sizeof( MAXROW ),fp);
  547.      }
  548. }
  549.